import { fetchSSE } from '@/utils/fetch';
import { makeAutoObservable, runInAction, observable } from 'mobx';
import { RefObject } from 'react';
import { RichEditorRef } from '@/components/editor/editor';
import { AgentConfig, getAgentInfo, getModelList } from '@/apis/public/agent';
import { getAgentInfo as initAgentInfo } from '@/apis/public/chat';
import { convertNodesToFormatMap } from '../utils';
import { callAIChat } from '@/apis/public/chat';
import { applyFormatToEditor, htmlContentToEditor } from '../utils';
import { Node } from 'slate';
import { ErrorData } from '../documentType';
import { message } from 'antd';
import { downloadFileById } from '@/apis/backhub/directory';
import { uploadFile } from '@/apis/public/upload';
import { converHtml2Word, getHtmlByFileId } from '@/apis/public/fileUpDownload';
import { Editor_Default_Directory } from '@/globals/document';
import { addDocument, updateDocument } from '@/apis/front/document';
import { Model } from '@/pages/backhub/model/store/modelTypes';

import { SlateDescendant, SlateTransforms } from '@wangeditor/editor';

// Tab项配置接口
interface AssistantItem {
  key: string;
  label: string;
}

interface AgentItem {
  id: number;
  agentInfo?: AgentConfig;
}

export const AssistantKeyMap = {
  writing: 'writing',
  format: 'format',
  polish: 'polish',
  proofread: 'proofread',
  outline: 'outline',
}

// 修改为导出类而不是实例
export class DocumentStore {
  // 会话ID
  sessionId: string = '';
  // 文档内容
  content: string = '';
  // 当前选中的助手标签
  activeTab: string = 'writing';
  // 是否正在处理中
  processing: boolean = false;
  // 当前处理事项信息
  processingInfo: { text: string } = { text: '' };
  // 编辑器引用
  editorRef: RefObject<RichEditorRef | null> | null = null;
  // 助手标签项
  assistantItems: AssistantItem[] = [
    { key: AssistantKeyMap.writing, label: '文件写作' },
    { key: AssistantKeyMap.proofread, label: '校对改错' },

    // { key: 'analysis', label: '公文解读'},
  ];
  agentMap: Record<string, AgentItem> = observable({
    [AssistantKeyMap.writing]: { id: 2 },
    [AssistantKeyMap.format]: { id: 3 },
    [AssistantKeyMap.outline]: { id: 4 },
  });

  lastSelectionText: string = '';

  // 添加 AbortController 属性
  private abortController: AbortController | null = null;

  // 模型列表
  modelList: Model[] = [];
  // 是否正在加载模型列表
  loadingModelList: boolean = false;

  // 文档表单信息
  documentForm: {
    id: string;
    title: string;
    keywords: string;
    desc: string;
    length: 'short' | 'medium' | 'long';
    docType: string;
    model?: string;
  } = {
      id: '',
      title: '',
      keywords: '',
      desc: '',
      length: 'short',
      docType: '',
    };

  constructor() {
    makeAutoObservable(this, {
      editorRef: false // 不观察引用类型
    });
  }

  // 初始化所有agent信息
  async initAgentInfo() {
    try {
      const promises = Object.values(this.agentMap).map(info =>
        this.fetchAgentInfo(info.id)
      );

      const results = await Promise.all(promises);
      const sessionResult = await initAgentInfo({ agentId: this.agentMap[AssistantKeyMap.writing].id });

      runInAction(() => {
        Object.keys(this.agentMap).forEach((key, index) => {
          this.agentMap[key].agentInfo = results[index];
        });
        this.sessionId = sessionResult.data?.sessionId;
        window.weditor = this.editorRef?.current?.getEditor();
      });
    } catch (error) {
      console.error('获取agent信息失败:', error);
    }
  }

  // 获取单个agent信息
  async fetchAgentInfo(id: number): Promise<AgentConfig> {
    try {
      return await getAgentInfo(id);
    } catch (error) {
      console.error(`获取agent(${id})信息失败:`, error);
      throw error;
    }
  }

  // 设置编辑器引用
  setEditorRef(ref: RefObject<RichEditorRef | null>) {
    this.editorRef = ref as RefObject<RichEditorRef>;
  }

  // 更新文档内容
  setContent(content: string) {
    this.content = content;
  }

  // 切换标签
  setActiveTab(tab: string) {
    this.activeTab = tab;
  }

  // 获取agent信息
  getAgentInfo(key: string): AgentConfig | undefined {
    return this?.agentMap?.[key]?.agentInfo;
  }

  // 获取模型列表
  async fetchModelList() {
    try {
      this.loadingModelList = true;
      const result: any = await getModelList();
      runInAction(() => {
        this.modelList = result.data;
      });
    } catch (error) {
      console.error('获取模型列表失败:', error);
      message.error('获取模型列表失败');
    } finally {
      runInAction(() => {
        this.loadingModelList = false;
      });
    }
  }

  // 获取模型选项（用于Select组件）
  getModelOptions() {
    return this.modelList
      .filter(model => model.isEnabled && model.status === 'active')
      .map(model => ({
        label: model.name,
        value: model.mark,
        disabled: !model.isEnabled || model.status !== 'active'
      }));
  }

  // 设置处理状态
  setProcessing(status: boolean) {
    this.processing = status;
  }

  // 设置处理信息
  setProcessingInfo(text: string) {
    this.processingInfo.text = text;
  }

  // 聚焦编辑器
  focusEditor(isEnd?: boolean) {
    if (this.editorRef?.current) {
      const editor = this.editorRef.current.getEditor();
      editor?.focus(isEnd);
    }
  }

  // 插入内容
  insertText(text: string) {
    if (!this.editorRef?.current) {
      return
    }
    const editor = this.editorRef.current.getEditor();
    if (!editor) {
      return;
    }
    editor.focus();
    editor.insertText(text);
  }

  // 保存文档
  async saveDocument() {
    try {
      this.setProcessing(true);
      const data = {
        id: this.documentForm.id,
        title: this.documentForm.title,
        content: this.content,
        type: this.documentForm.docType,
        keywords: this.documentForm.keywords,
        remark: this.documentForm.desc,
        sessionId: this.sessionId,
        chatSessionId: 0,
      }
      let res;
      if (!data.id) {
        res = await addDocument(data);
      } else {
        res = await updateDocument(data);
      }
      if (res.status && res.data.success) {
        this.documentForm.id = res.data.dataId;
        message.success('保存成功');
      } else {
        message.error("保存失败：" + res.data.message);
      }
    } catch (error) {
      message.error(error instanceof Error ? error.message : '保存失败');
    } finally {
      this.setProcessing(false);
    }
  }

  // 智能写作
  async generateContent(params: {
    type: string | 'outline' | 'writing';
    userMessage: string;
    additionalParams?: Record<string, string | number | boolean | object>;
    onFinish?: (text: string, context?: Record<string, string | number | boolean | object>) => void;
    onError?: (error: string) => void;
  }) {
    try {
      const currentAgent = this.getAgentInfo(params.type);
      if (!currentAgent) {
        message.error('智能体配置错误');
        return;
      }

      this.newAbortController();
      this.setProcessing(true);
      this.setProcessingInfo('正在写作中...');
      this.focusEditor();

      const useStreamOutput = currentAgent?.streamOutput === 1;
      const modelToUse = currentAgent?.fixedModel || '';
      const body = {
        sessionId: this.sessionId,
        userMessage: params.userMessage,
        agentId: currentAgent.id,
        additionalParams: params.additionalParams,
        mark: currentAgent.fixedModel,
        type: params.type,
        selectedModel: this.documentForm?.model
      }
      let content = "" as string | undefined
      await fetchSSE(`/api/starhub/chat/callStream`, {
        method: 'post',
        body: JSON.stringify(body),
        headers: {
          'Content-Type': 'application/json',
        },
        signal: this.abortController.signal,
        onAbort: async (text) => {
          console.log("onAbort", text)
        },
        onMessageHandle: async (chunk) => {
          switch (chunk.type) {
            case 'text': {
              content += chunk.text;
              if (content.startsWith('\\n') || content.startsWith('\n')) {
                content = content.replace(/^[\\n\n]+/, '');
              }
              this.setContent(content!);
            }
          }
        },
        onFinish: async (text, context) => {
          content = undefined
          if (params.onFinish) {
            params.onFinish(text, context)
          }
        },
        onErrorHandle: (err) => {
          message.error(err.message ?? '生成失败');
          if (params.onError) {
            params.onError(err.message)
          }
          this.abortController?.abort();
        }
      })
    } catch (error) {
      message.error(error instanceof Error ? error.message : '生成失败');
    } finally {
      this.setProcessing(false);
      this.setProcessingInfo('');
      this.abortController = null;
    }
  }

  // 一键排版
  async formatContent(params: {
    templateId: string;
  }): Promise<void> {
    try {
      const editor = this.editorRef?.current?.getEditor();
      if (!editor) {
        return;
      }
      this.newAbortController();
      this.setProcessing(true);
      this.setProcessingInfo('正在排版中...');
      const formatted = convertNodesToFormatMap(editor.children)
      const data = {
        sessionId: this.sessionId,
        userMessage: JSON.stringify(formatted),
        agentId: this.agentMap[AssistantKeyMap.format]?.id || 3,
        additionalParams: {},
        promptName: "",
        functionName: "",
        selectedModel: this.documentForm?.model
      }
      const res = await callAIChat(data, this.abortController.signal)
      // 处理格式化响应
      if (res.data?.success && res.data?.message) {
        const editor = this.editorRef?.current?.getEditor();
        const formatResult = res.data.message?.replace(/^[\\n\n]+/, '');
        if (editor) {
          // 应用格式，根据模板ID确定文档类型
          const docType = params.templateId === '通知' ? 'tz' : 'bg';
          applyFormatToEditor(editor, formatResult, docType as 'bg' | 'tz');
        }
      } else {
        throw new Error(res.data?.message || '排版失败');
      }
    } catch (error) {
      if (error === "canceled" || (error as TypeError).name === 'AbortError') {
        return;
      }
      message.error(error instanceof Error ? error.message : '排版失败');
      throw error; // 重新抛出错误，以便调用方能够捕获
    } finally {
      this.setProcessing(false);
      this.setProcessingInfo('');
      this.abortController = null;
    }
  }

  // 智能润色
  async polishContent() {
    try {
      this.setProcessing(true);
      // TODO: 调用润色接口
    } catch (error) {
      message.error(error instanceof Error ? error.message : '润色失败');
    } finally {
      this.setProcessing(false);
    }
  }

  // 智能校对
  async proofreadContent() {
    try {
      this.setProcessing(true);
      // TODO: 调用校对接口
    } catch (error) {
      message.error(error instanceof Error ? error.message : '校对失败');
    } finally {
      this.setProcessing(false);
    }
  }

  // 公文解读
  async analyzeDocument() {
    try {
      this.setProcessing(true);
      // TODO: 调用解读接口
    } catch (error) {
      message.error(error instanceof Error ? error.message : '解读失败');
    } finally {
      this.setProcessing(false);
    }
  }

  /**
   * 选中纠错文字
   * @param originalText
   */
  selectError(originalText: string) {
    const editor = this.editorRef?.current?.getEditor();

    if (!editor) {
      return;
    }

    // 移除前一次选中效果
    this.removeLastSelection();

    // 查找目标文字位置
    let position: any = null;
    let curNode: any = null;
    for (const [node, path] of Node.texts(editor as any)) {
      const { text } = node; // 当前文本节点的内容

      const index = text.indexOf(originalText); // 查找目标文字
      if (index !== -1) {
        // 如果找到，记录路径和偏移量
        curNode = node;
        position = { path, offset: index };
        break; // 找到后终止遍历
      }
    }

    // 如果找到目标文字，则设置选中状态
    if (position) {
      const newSelection = {
        anchor: { path: position.path, offset: position.offset },
        focus: { path: position.path, offset: position.offset + originalText.length }
      }
      editor?.select(newSelection);
      editor?.addMark('bold', true);
      editor?.addMark('color', 'red');

      //滚动到错误位置
      try {
        const elem = editor.toDOMNode(curNode)
        editor.scrollToElem(elem.id)
      } catch (e) {
        console.log('e', e);
      }
    }
    this.lastSelectionText = originalText;
  }

  /**
   * 移除前一次选中效果
   */
  removeLastSelection = () => {
    if (!this.lastSelectionText) {
      return;
    }

    const editor = this.editorRef?.current?.getEditor();
    if (!editor) {
      return;
    }

    let position0: any = null;
    for (const [node, path] of Node.texts(editor as any)) {
      const { text } = node; // 当前文本节点的内容

      const index = text.indexOf(this.lastSelectionText); // 查找目标文字
      if (index !== -1) {
        // 如果找到，记录路径和偏移量
        position0 = { path, offset: index };
        break; // 找到后终止遍历
      }
    }

    if (position0) {
      const newSelection = {
        anchor: { path: position0.path, offset: position0.offset },
        focus: { path: position0.path, offset: position0.offset + this.lastSelectionText.length }
      }

      // 先移除已有标记
      editor?.select(newSelection);
      editor?.removeMark('bold')
      editor?.removeMark('color')
      this.lastSelectionText = '';
    }
  }

  /**
   * 替换文字
   * @param errorText
   * @param correctText
   */
  replaceText = (errorText: string, correctText: string) => {
    const editor = this.editorRef?.current?.getEditor();
    if (!editor) {
      return;
    }
    // 移除选中效果
    this.removeLastSelection();

    let html = editor.getHtml();
    html = html.replace(errorText, correctText);
    editor.setHtml(html);
  }

  /**
   * 全部接受
   * @param errorDatas 
   */
  acceptAllError = (errorDatas: ErrorData[]) => {
    const editor = this.editorRef?.current?.getEditor();
    if (!editor) {
      return;
    }
    errorDatas.forEach(errorData => {
      this.replaceText(errorData.originalText, errorData.result);
    });
  }

  /**
   * 导出文件
   * @returns 
   */
  handleExport = async () => {
    try {
      const editor = this.editorRef?.current?.getEditor();
      if (!editor) {
        message.error('获取编辑器实例失败');
        return;
      }
      const fileName = this.documentForm.title ? this.documentForm.title + '.docx' : '正文.docx';
      const res = await converHtml2Word({ html: editor.getHtml(), fileName, directoryId: Editor_Default_Directory })
      if (res.status) {
        await downloadFileById(res.data.id, fileName)
      }
    } finally {
    }
  }

  handleUpload1 = async () => {
    const editor = this.editorRef?.current?.getEditor();
    if (!editor) {
      return;
    }
    const htmlDatas = "<div><span>1001</span><span>1002</span><span>1003</span><span>1004</span><br><span>1005</span><span>1006</span><span>1007</span><span>1008</span></div>"

    const html = editor.getHtml();
  }

  handleUpload = async () => {
    // 创建一个临时的上传组件来触发文件选择
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = '.pdf,.doc,.docx';
    input.style.display = 'none';

    input.onchange = async (event: Event) => {
      const target = event.target as HTMLInputElement;
      const file = target.files?.[0];

      if (!file) return;

      try {
        // 检查文件类型
        const isValidFileType = [
          'application/pdf',
          'application/msword',
          'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
        ].includes(file.type);

        if (!isValidFileType) {
          message.error('只能上传PDF、DOC或DOCX文件');
          return;
        }

        // 检查文件大小（限制为20MB）
        const maxSize = 20 * 1024 * 1024;
        if (file.size > maxSize) {
          message.error('文件大小不能超过20MB');
          return;
        }

        // 构建上传参数
        const formData = new FormData();
        formData.append('file', file);
        formData.append('fileName', file.name);
        formData.append('uid', Date.now().toString());
        formData.append('directoryId', Editor_Default_Directory.toString());

        // 调用上传接口
        const response = await uploadFile(formData);

        if (response && response.data && response.data.page && response.data.page.length > 0) {
          const fileId = response.data.page[0].id;

          // 调用获取文件内容接口
          const contentRes = await getHtmlByFileId({
            id: fileId,
            fileName: file.name,
            filePath: '',
            directoryId: Editor_Default_Directory,
            userId: Number(window.HubUser?.id || 0),
            pageNo: 0,
            pageSize: 0,
            html: ''
          });

          if (contentRes.code === 200 && contentRes.data && contentRes.data.success && contentRes.data.docContent) {
            // 将获取的HTML内容输出到文本编辑器
            const editor = this.editorRef?.current?.getEditor();
            if (editor) {
              // 获取当前编辑器内容
              const currentContent = editor.getHtml();
              // 在末尾添加文件内容
              const { content, detail } = contentRes.data.docContent;
              editor.setHtml(content);
              htmlContentToEditor(editor, detail);
              // 显示成功消息
              message.success('文件内容已成功添加到编辑器中');
            } else {
              message.error('获取编辑器实例失败');
            }
          } else {
            message.error('获取文件内容失败');
          }
        } else {
          message.error('文件上传失败');
        }
      } catch (error) {
        console.error('上传文件失败:', error);
        const { message } = await import('antd');
        message.error('上传文件失败，请重试');
      } finally {
        // 清理临时元素
        document.body.removeChild(input);
      }
    };

    // 添加到DOM并触发点击
    document.body.appendChild(input);
    input.click();
  }

  newAbortController() {
    if (this.abortController) {
      this.abortController.abort();
      this.abortController = null;
    }
    this.abortController = new AbortController();
  }

  // 添加取消方法
  cancelOperation() {
    if (this.abortController) {
      this.abortController.abort();
      this.abortController = null;
      this.setProcessing(false);
      this.setProcessingInfo('');
    }
  }

  // 更新文档表单信息
  setDocumentForm(formData: Partial<typeof this.documentForm>) {
    this.documentForm = {
      ...this.documentForm,
      ...formData
    };
  }

  // 重置文档表单信息
  resetDocumentForm() {
    this.documentForm = {
      id: '',
      title: '',
      keywords: '',
      desc: '',
      length: 'short',
      docType: '',
    };
  }
} 